PROJECT = "httpdemo"
VERSION = "1.0.0"

_G.sys = require("sys")
--_G.mqtt = require("mqtt")
_G.mqtt2 = require("mqtt2")

WeatherId = {
    --暴雪 0
    "大雪", -- 1
    "暴雪", -- 2
    "大到暴雪", -- 3
    --暴雨 1
    "大雨", -- 4
    "暴雨", -- 5
    "大暴雨", -- 6
    "特大暴雨", -- 7
    "中到大雨", -- 8
    "大到暴雨", -- 9
    "暴雨到大暴雨", -- 10
    "大暴雨到特大暴雨", -- 11
    --多云 4
    "多云", -- 12
    -- 浮尘 6
    "浮尘", -- 13
    "霾", -- 14
    "中度霾", -- 15
    "重度霾", -- 16
    "严重霾", -- 17
    --雷阵雨 7
    "雷阵雨", -- 18
    "雷阵雨伴有冰雹", -- 19
    --晴天 8
    "晴", -- 20
    -- 12
    "沙尘暴", -- 21
    "强沙尘暴", -- 22
    "龙卷风", -- 23
    -- 17
    "雾", -- 24
    "浓雾", -- 25
    "轻雾", -- 26
    "强浓雾", -- 27
    "大雾", -- 28
    "特强浓雾", -- 29
    -- 18
    "小雨", -- 30
    "中雨", -- 31
    "小到中雨", -- 32
    "雨", -- 33
    -- 19
    "扬沙", -- 34
    -- 20
    "阴", -- 35
    -- 21
    "雨夹雪", -- 36
    -- 22
    "阵雨", -- 37
    -- 23
    "阵雪", -- 38
    "小雪", -- 39
    "中雪", -- 40
    "小到中雪", -- 41
    "中到大雪", -- 42
    "弱高吹雪", -- 43
    "雪", -- 44
    -- 暂无
    "冻雨", -- 45
    "暂无" -- 46
}

L1Status = 0 --灯开关
F1Status = 0 -- 风扇开关
--串口初始化
local uartid = 1
local result = uart.setup(
    uartid,--串口id
    115200,--波特率
    8,--数据位
    1--停止位
)

--MQTT发送函数
function MQTTSend(status,device)
    if _G.mqttc and _G.mqttc.stat == 1 then
        if device == 0 then --灯控制
            if status == 1 then
                sys.taskInit(function()
                    _G.mqttc:pub("Ldevice", 0, "{\"status\":1}")--开灯
            end) 
            else
                sys.taskInit(function()
                _G.mqttc:pub("Ldevice", 0, "{\"status\":0}")--关灯
                end)
            end
        elseif device == 1 then --风扇控制
            if status == 1 then
                sys.taskInit(function()
                    _G.mqttc:pub("Fdevice", 0, "{\"status\":1}")--开灯
            end) 
            else
                sys.taskInit(function()
                _G.mqttc:pub("Fdevice", 0, "{\"status\":0}")--关灯
                end)
            end
        end
    end
end

--处理串口数据
local function proc(data)
    if not data then return end    
    --log.info("data analysis")
    --寻找帧头0xAA
    local head = string.find(data,string.char(0x5A))
    if not head then return false,data end    
    
    local len,states,Add_H,Add_L,D_len,Data_H,Data_L = string.byte(data,head+2,-1) --从帧头到末尾分割
    --log.info("recieve data is ",len,states,Add_H,Add_L,D_len,Data_H,Data_L)

    if Add_L == 0x10 and L1Status == 0 then -- 灯
        L1Status = 1
        --log.info("L status","true ")
        MQTTSend(1,0)
        IconNumShow(0x5011,1)
    elseif Add_L == 0x10 and L1Status == 1 then -- 灯
        L1Status = 0
        --log.info("L status","false ")
        MQTTSend(0,0)
        IconNumShow(0x5011,0)
    elseif Add_L == 0x12 and F1Status == 0 then -- 风扇
        F1Status = 1
        --log.info("F status","true ")
        MQTTSend(1,1)
        IconNumShow(0x5013,1)
    elseif Add_L == 0x12 and F1Status == 1 then -- 风扇
        F1Status = 0
        --log.info("F status","false ")
        MQTTSend(0,1)
        IconNumShow(0x5013,0)
    else
        --log.info("status","is over ")
    end
end

--接收串口数据
local function read()
    local data = ""
    while true do        
        data = uart.read(uartid,9)
        --数据不存在时停止接收数据
        if not data or string.len(data) == 0 then break end
        --打开下面的打印会耗时
        --log.info("testUart.read hex",data:toHex())
        --真正的串口数据处理函数
        proc(data)
    end
end

uart.on(uartid,"receive",read) -- 注册串口接收服务

-- wifi链接函数
if wlan ~= nil then
    log.info("mac", wlan.get_mac())
    local ssid = "AI"
    local password = "12345687"
    wlan.connect(ssid, password)
end

--更换图标函数 Add图标地址 ID显示序号
function IconNumShow(Add,ID)
    local Data = {0,0,0,0,0,0,0,0}
    Data[1] = 0x5A
    Data[2] = 0xA5
    Data[3] = 0x05    --长度
    Data[4] = 0x82
    Data[5] = (Add & 0xFF00) >> 8
    Data[6] = Add & 0xFF
    Data[7] = (ID & 0xFF00) >> 8
    Data[8] = ID & 0xFF
    local Str = string.char(Data[1],Data[2],Data[3],Data[4],Data[5],Data[6],Data[7],Data[8])
    uart.write(uartid,Str)
end

--计算星期 基姆拉尔森计算公式
function GetWeek(Year,Mouth,Day)
    Year = tonumber(Year)
    Mouth = tonumber(Mouth)
    Day = tonumber(Day)

    if Mouth == 1 or Mouth == 2 then
        Year = Year - 1
        Mouth = Mouth + 12
    end
    
    local week = (Day+ 1 +2*Mouth+3*(Mouth+1)/5+Year+Year/4-Year/100+Year/400)%7
    if (week - math.floor(week))>= 0.5 then
        week = math.floor(week) + 1
    else
        week = math.floor(week)
    end
    if week >= 0 and week <= 6 then
        return week
    else
        return 0
    end
    
    --log.info("week",week)
end
--RTC刷新函数 Add数据地址 Num显示数值
function RTCShow(Year,Mouth,Day,Hour,Min,Sec)
    local Data = {0,0,0,0,0,0,0,0,0,0,0,0,0,0}
    Data[1] = 0x5A
    Data[2] = 0xA5
    Data[3] = 0x0B    --长度
    Data[4] = 0x82
    Data[5] = 0x00
    Data[6] = 0x10
    Data[7] = Year - 2000
    Data[8] = Mouth
    Data[9] = Day
    Data[10] = GetWeek(Year,Mouth,Day)
    Data[11] = Hour
    Data[12] = Min
    Data[13] = Sec
    Data[14] = 0x00
    local Str = string.char(Data[1],Data[2],Data[3],Data[4],Data[5],Data[6],Data[7],Data[8],Data[9],Data[10],Data[11],Data[12],Data[13],Data[14])
    uart.write(uartid,Str)
end

-- 天气判断函数
function WeatherSwitch(WeatherIdi)
    if WeatherIdi <= 3 then
        WeatherIdi = 0
    elseif WeatherIdi > 3 and WeatherIdi <= 11 then
        WeatherIdi = 1
    elseif WeatherIdi == 12 then
        WeatherIdi = 4
    elseif WeatherIdi >= 13 and WeatherIdi <= 17 then
        WeatherIdi = 6
    elseif WeatherIdi >= 18 and WeatherIdi <= 19 then
        WeatherIdi = 7
    elseif WeatherIdi == 20 then
        WeatherIdi = 8
    elseif WeatherIdi >= 21 and WeatherIdi <= 23 then
        WeatherIdi = 12
    elseif WeatherIdi>=24 and WeatherIdi <= 29 then
        WeatherIdi = 17
    elseif WeatherIdi >= 30 and WeatherIdi <= 33 then
        WeatherIdi = 18
    elseif WeatherIdi == 34 then
        WeatherIdi = 19
    elseif WeatherIdi == 35 then
        WeatherIdi = 20
    elseif WeatherIdi == 36 then
        WeatherIdi = 21
    elseif WeatherIdi == 37 then
        WeatherIdi =22
    elseif WeatherIdi >= 38 and WeatherIdi <= 44 then
        WeatherIdi = 23
    else
        WeatherIdi = 0
    end

    return WeatherIdi --返回天气值
end

--协程一 天气信息获取
sys.taskInit(
    function()
        -- 等待联网成功
        while true do
            while not socket.isReady() do
                --log.info("net", "wait for network ready")
                sys.waitUntil("NET_READY", 1000)
                IconNumShow(0x5014,1) -- WIFI未连接
            end
            IconNumShow(0x5014,0) -- WIFI已连接
            sys.wait(5000)
            http.get(
                "http://api.map.baidu.com/weather/v1/?district_id=130111&data_type=now&ak=**************************",
                nil,
                function(code, headers, body)
                    local WeatherIdi = 1 -- 天气索引值
                    local MyJson,result = json.decode(body)
                    if result then
                        Temp = MyJson.result.now.temp -- 温度
                        Hum = MyJson.result.now.rh -- 相对湿度
                        IconNumShow(0x5001,Temp) -- 发送温度
                        IconNumShow(0x5003,Hum) -- 发送湿度
                        while MyJson.result.now.text ~= WeatherId[WeatherIdi] do --检索当前天气
                            WeatherIdi = WeatherIdi + 1
                        end
                        -- log.info(" Weather ID is ",WeatherIdi) -- 查表获得的天气序号
                        WeatherIdi = WeatherSwitch(WeatherIdi) -- 获取串口屏天气序号
                        IconNumShow(0x5000,WeatherIdi) -- 串口屏显示天气图标
                        -- log.info(" Show Weather ID is ",WeatherIdi) -- 要显示的天气序号
                        
                    else
                        --log.error("data","error")
                    end
                end
            )
            sys.wait(5000)
            http.get(
                "http://api.map.baidu.com/weather/v1/?district_id=130111&data_type=fc&ak=**************************",
                --获取预报天气
                nil,
                function(code, headers, body)
                    local WeatherIdFCi = 1
                    local FCJson,result = json.decode(body)
                    if result then
                        HTemp = FCJson.result.forecasts[1].high -- 最高温
                        LTemp = FCJson.result.forecasts[1].low -- 最低温
                        IconNumShow(0x500A,HTemp) -- 发送最高温
                        IconNumShow(0x500C,LTemp) -- 发送最低温
                        while FCJson.result.forecasts[1].text_day ~= WeatherId[WeatherIdFCi] do --检索当前天气
                            WeatherIdFCi = WeatherIdFCi + 1
                        end
                        WeatherIdFCi = WeatherSwitch(WeatherIdFCi) -- 获取串口屏天气序号
                        IconNumShow(0x5009,WeatherIdFCi) -- 串口屏显示天气图标
                        --log.info("high",HTemp)
                        --log.info("low",LTemp)
                        --log.info(" Show FC Weather ID is ",WeatherIdFCi) -- 要显示的天气序号
                    else
                        --log.error("forecasts","error")
                    end
                end
            )
            sys.wait(1000 * 600)
        end
    end
)

--协程二 时间刷新
sys.taskInit(
    function ()
        while true do
            while not socket.isReady() do
                sys.waitUntil("NET_READY", 1000) --等待设备连接
            end
            t_sec = 0
            http.get(
                "http://quan.suning.com/getSysTime.do",
                --http://quan.suning.com/getSysTime.do 苏宁时间接口
                nil,
                function(code, headers, body)
                    local TMJson,result = json.decode(body)
                    if result then
                        --log.info("time",TIME)
                        local TIME = TMJson.sysTime1 -- 时间
                        local t_year = string.sub(TIME,1,4)--取出年份
                        local t_month = string.sub(TIME,5,6)--取出月份
                        local t_day = string.sub(TIME,7,8)--取出日
                        local t_hour = string.sub(TIME,9,10)--取出时
                        local t_min = string.sub(TIME,11,12)--取出分
                        t_sec = string.sub(TIME,13,14)--取出秒
                        -- log.info("testNtp.printTime", string.format("%04d/%02d/%02d,%02d:%02d:%02d", t_year, t_month, t_day, t_hour, t_min, t_sec))
                        RTCShow(t_year,t_month,t_day,t_hour,t_min,t_sec) -- 时间发送
                    end
                end
            )
            sys.wait(1000 * (61 - t_sec))
        end
    end
)
--线程三 MQTT连接函数
sys.taskInit(function()
    local clientId = "air640"
    local host, port = "123.**.**.***", 1883
    local sub_topics = {}
    local topic_req = string.format("/device/%s/req", clientId)
    sub_topics[topic_req] = 1
    while not socket.isReady() do --等待设备连接
        sys.waitUntil("NET_READY", 1000)
    end

    _G.mqttc = mqtt2.new(clientId, 60, "admin", "public", 0, host, port, sub_topics, function(pkg)
        --{"Num":100}
        log.info("recieve",pkg)
        -- local RJson,result = json.decode(pkg)
        log.info("recieve result",pkg.payload)
        --IconNumShow(0x5017,RJson.Num) -- 数据显示
    end, "mqtt_airm2m")
    IconNumShow(0x5016,1) -- MQTT已连接
    mqttc:run() -- 会一直阻塞在这里
end
)


-- 用户代码已结束---------------------------------------------
-- 结尾总是这一句
sys.run()